package org.example.supplychain.service;

import org.example.supplychain.domain.Material;
import org.example.supplychain.domain.Order;
import org.example.supplychain.mapper.MaterialMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 原材料service
 **/
@Service
public class MaterialService {

    @Autowired
    private MaterialMapper mMapper;
    @Autowired
    private OrderService ors;

    /**
     * 向数据库中添加材料信息
     *
     * @param material 原料实例
     */
    public void addMaterial(Material material) {
        mMapper.addMaterial(material);
    }

    /**
     * 向数据库中添加材料信息
     *
     * @param materialName     原料名称
     * @param supplierName     供应商名称
     * @param averageUnitPrice 平均单价
     */
    public void addMaterial(String materialName, String supplierName, double averageUnitPrice) {
        Material material = new Material();
        material.setMaterialName(materialName);
        material.setSupplierName(supplierName);
        material.setAverageUnitPrice(averageUnitPrice);
        mMapper.addMaterial(material);
    }

    /**
     * 根据id删除数据库中材料信息
     *
     * @param materialId 原料id
     */
    public void deleteMaterialByMaterialId(long materialId) {
        mMapper.deleteMaterialByMaterialId(materialId);
    }

    /**
     * 根据id更新材料价格
     *
     * @param material 原料实例
     */
    public void updateMaterial(Material material) {
        mMapper.updateMaterial(material);
    }

    /**
     * 根据id获取材料信息
     *
     * @param materialId 原料id
     * @return Material
     */
    public Material getMaterialByMaterialID(long materialId) {
        return mMapper.getMaterialByMaterialId(materialId);
    }

    /**
     * 根据materialName获取材料信息
     * @param materialName 原料名
     * @return List</Material>
     */
    public List<Material> getMaterialByMaterialName(String materialName) {
        return mMapper.getMaterialByMaterialName(materialName);
    }

    /**
     * 根据供应商名字获取材料信息
     * @param supplierName 供应商名字
     * @return List<Material>
     */
    public List<Material> getMaterialBySupplierName(String supplierName) {
        return mMapper.getMaterialBySupplierName(supplierName);
    }

    /**
     * 计算传入的某原材料的均价（根据订单列表）
     * （注意只有 同一 个供应商下的 同名 原料才算为同种原材料）
     * @param materialName 材料名
     * @param supplierName 供应商名
     */
    public void updateSingleMaterialAverageUnitPrice(String materialName, String supplierName){
        Material material=mMapper.getMaterialByMaterialNameAndSupplierName(materialName,supplierName);
        List<Order> allOrders=ors.getAllOrders();
        double averagePrice=0;
        int num=0;
        for(Order o:allOrders){
            if(o.getMaterialName().equals(materialName) && o.getSupplierName().equals(supplierName)){
                num++;
                averagePrice+=o.getAverageUnitPrice();
            }
        }
        averagePrice/=num;
        material.setAverageUnitPrice(averagePrice);
        mMapper.updateMaterial(material);
    }

    /**
     * 计算所有原材料的均价（注意只有同一个供应商下的同名原料才算为同种原材料）
     * 根据订单列表进行计算
     */
    public void updateMaterialAverageUnitPrice(){
        List<Order> allOrders=ors.getAllOrders();
        Set<String[]> nameSet=new HashSet<>();
        for(Order o:allOrders){
            String[] str=new String[2];
            str[0]=o.getMaterialName();
            str[1]=o.getSupplierName();
            nameSet.add(str);
        }
        for(String[] str:nameSet){
            updateSingleMaterialAverageUnitPrice(str[0],str[1]);
        }
    }

    /**
     * 预测原料接下来的价格
     * @return double
     */
    public double predictMaterialPrice(String materialName, String supplierName){
        List<Order> allOrders=ors.getAllOrders();
        double predictPrice=0;
        int index=0;
        for(Order o:allOrders){
            if(o.getMaterialName().equals(materialName) && o.getSupplierName().equals(supplierName))
                index++;
        }
        int iniIndex=index;
        for(Order o:allOrders){
            if(o.getMaterialName().equals(materialName) && o.getSupplierName().equals(supplierName)){
                predictPrice+=o.getAverageUnitPrice()*index;
                index--;
            }
        }
        predictPrice/=iniIndex;
        predictPrice/=(iniIndex+1);
        predictPrice/=2;
        return predictPrice;
    }

    /**
     * 预测原料接下来需求数量
     * @return long
     */
    public long predictMaterialNeed(String materialName, String supplierName){
        List<Order> allOrders=ors.getAllOrders();
        long predictNeed=0;
        long index=0;
        for(Order o:allOrders){
            if(o.getMaterialName().equals(materialName) && o.getSupplierName().equals(supplierName))
                index++;
        }
        long iniIndex=index;
        for(Order o:allOrders){
            if(o.getMaterialName().equals(materialName) && o.getSupplierName().equals(supplierName)){
                predictNeed+=o.getMaterialNumber()*index;
                index--;
            }
        }
        predictNeed/=iniIndex;
        predictNeed/=(iniIndex+1);
        predictNeed/=2;
        return predictNeed;
    }
}
